﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Dynamics.BusinessConnectorNet;
using System.Collections;
using PJ.Framework.DynamicsAX;

namespace PJ.Data
{
    /// <summary>
    /// Dynamics AX server implementation of <see cref="IEntityProvider"> persistence interface. 
    /// </summary>
    /// <typeparam name="TDataInterface">Entity data interface type</typeparam>
    /// <typeparam name="TDataConcreteClass">Entity data concrete class type</typeparam>
    public abstract class EntityFragmentAXProvider
    {
        /// <summary>
        /// Finds a <see cref="IEntityData">owner</see> fragment list
        /// </summary>
        /// <param name="ownerId"><see cref="IEntityData">owner</see> id</param>
        /// <returns>List of fragments global ids or <see langword="null" /> if no fragments found</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="ownerId"/> is <see langword="null" /> or empty.</exception>
        public static string[] GetFragments(Type providerType, IEntityFragmentCache cache , string ownerId, GetDataMode mode)
        {
            if (ownerId == null || ownerId == "")
                throw new ArgumentNullException("ownerId");
            string[] fragments = null;
            if (cache != null && (mode & GetDataMode.UseCache) == GetDataMode.UseCache)
                fragments = cache.FindFragments(ownerId);
            if (fragments == null)
            {
                using (AxaptaContainer container =
                    (AxaptaContainer)DynamicsAXBroker.StaticMethod(providerType.Name, "FindFragments", ownerId))
                {
                    int count = container.Count;
                    if (count > 0)
                    {
                        List<string> list = new List<string>();
                        for (int i = 0; i < count; i += 2)
                            list.Add(ObjectAXProvider<IEntityFragmentData>.GetGlobalId(providerType, (int)container.get_Item(i + 1), (Int64)container.get_Item(i + 2)));
                        if (cache != null)
                            cache.AddFragments(ownerId, list.ToArray());
                        fragments = list.ToArray();
                    }
                }
            }
            if (fragments == null && (mode & GetDataMode.Find) != GetDataMode.Find)
                throw new DataNotFoundException("ownerId", ownerId);
            return fragments;
        }

        /// <summary>
        /// Copies items from the AX container
        /// </summary>
        /// <param name="enumerator">Enumerator of the AX container</param>
        /// <param name="data">Copy to object</param>
        public static void CopyFromContainer(IEnumerator enumerator, IEntityFragmentData data)
        {
            if (enumerator.MoveNext())
                data.OwnerId = ((string)enumerator.Current).Trim();
            else
                throw new ArgumentException("Container size error", "enumerator");
        }
    }
}
